page.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * 定价页 - 面包屑 + 页头 + 汇率提示 + 4 行完整价格表 + 扣费规则 + 定价 FAQ + 模型大全入口
  3. */
  4. import { Suspense } from 'react';
  5. import Link from 'next/link';
  6. import { useLocale, useTranslations } from 'next-intl';
  7. import { SiteHeader } from '@/components/SiteHeader';
  8. import { SiteFooter } from '@/components/SiteFooter';
  9. import { SupportFab } from '@/components/SupportFab';
  10. import { AuthModal } from '@/components/AuthModal';
  11. import { RateBox } from '@/components/pricing/RateBox';
  12. import { PriceTable } from '@/components/pricing/PriceTable';
  13. import { BillingRules } from '@/components/pricing/BillingRules';
  14. import { PricingFaq } from '@/components/pricing/PricingFaq';
  15. export default function PricingPage() {
  16. const t = useTranslations();
  17. const locale = useLocale();
  18. // BreadcrumbList 结构化数据
  19. const breadcrumbJson = {
  20. '@context': 'https://schema.org',
  21. '@type': 'BreadcrumbList',
  22. itemListElement: [
  23. { '@type': 'ListItem', position: 1, name: 'Home', item: `${siteUrl()}/${locale}` },
  24. { '@type': 'ListItem', position: 2, name: 'Pricing', item: `${siteUrl()}/${locale}/pricing` },
  25. ],
  26. };
  27. return (
  28. <div className="flex min-h-screen flex-col">
  29. <script
  30. type="application/ld+json"
  31. dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbJson) }}
  32. />
  33. <SiteHeader />
  34. <main className="flex-1">
  35. <div className="mx-auto max-w-[1160px] px-6 py-8">
  36. {/* 面包屑 */}
  37. <nav className="mb-6 flex items-center gap-2 text-[13px] text-brand-muted" aria-label="Breadcrumb">
  38. <Link href={`/${locale}`} className="transition-colors hover:text-brand-purple-l">
  39. {t('crumb_home')}
  40. </Link>
  41. <span className="opacity-50">/</span>
  42. <span className="text-brand-text">{t('nav_pricing')}</span>
  43. </nav>
  44. {/* 页头 */}
  45. <div className="mb-6 max-w-[720px]">
  46. <h1 className="mb-2 text-[30px] font-extrabold tracking-tight">{t('price_h1')}</h1>
  47. <p className="text-sm text-brand-muted">{t('price_sub')}</p>
  48. </div>
  49. {/* 汇率提示 */}
  50. <div className="max-w-[820px]">
  51. <RateBox />
  52. </div>
  53. {/* 完整价格表 */}
  54. <section className="mt-8">
  55. <PriceTable />
  56. <p className="mt-2.5 text-[12.5px] text-brand-muted">{t('price_note')}</p>
  57. <div className="mt-3.5 flex flex-wrap items-center gap-5">
  58. <Link
  59. href={`/${locale}/pricing/catalog`}
  60. className="inline-block text-sm font-semibold text-brand-purple-l transition-colors hover:text-brand-text"
  61. >
  62. 📚 View all 236 models &amp; pricing → (Model Catalog)
  63. </Link>
  64. <Link
  65. href={`/${locale}/models`}
  66. className="inline-block text-sm font-semibold text-brand-purple-l transition-colors hover:text-brand-text"
  67. >
  68. {t('detail_rel_view')}
  69. </Link>
  70. </div>
  71. </section>
  72. {/* 扣费规则 */}
  73. <section className="mt-10">
  74. <BillingRules />
  75. </section>
  76. {/* 定价 FAQ */}
  77. <div className="mt-10">
  78. <PricingFaq />
  79. </div>
  80. </div>
  81. </main>
  82. <SiteFooter />
  83. <SupportFab />
  84. <Suspense fallback={null}>
  85. <AuthModal />
  86. </Suspense>
  87. </div>
  88. );
  89. }
  90. import type { Metadata } from 'next';
  91. import { alternatesFor, pageMeta, siteUrl } from '@/lib/seo';
  92. type MetaProps = { params: Promise<{ locale: string }> };
  93. export async function generateMetadata({ params }: MetaProps): Promise<Metadata> {
  94. const { locale } = await params;
  95. const m = pageMeta(locale, 'pricing');
  96. return { title: m.title, description: m.desc, alternates: alternatesFor('/pricing', locale) };
  97. }